﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace CPPEI.ETL.Domain.Services
{
    public class DimService
    {
        public ServiceResult<Entities.EDim> CreateDim(string userId, string code, string name)
        {
            using(EtlDbContext dbContext = new EtlDbContext())
            {
                EntityRepository<Entities.EDim> dRep = new EntityRepository<Entities.EDim>(dbContext);

                Entities.EDim eDim = new Entities.EDim();
                eDim.Id = Guid.NewGuid();
                eDim.Code = code;
                eDim.Name = name;
                eDim.IsDeleted = false;
                eDim.IsEnabled = true;
                eDim.CreatedTime = DateTime.Now;
                eDim.Creator = userId;

                dRep.Create(eDim);

                if(dbContext.SaveChanges() > 0)
                {
                    return new ServiceResult<Entities.EDim>(true, ErrorCode.COM_NoError, string.Empty, eDim);
                }
                else
                {
                    return new ServiceResult<Entities.EDim>(false, ErrorCode.COM_DBError, string.Empty);
                }
            }
        }

        public ServiceResult<Entities.EDimItem> CreateDimItem(string userId, Guid dimId, string code, string name, DateTime effectiveDate, DateTime expiryDate)
        {
            using (EtlDbContext dbContext = new EtlDbContext())
            {
                EntityRepository<Entities.EDimItem> diRep = new EntityRepository<Entities.EDimItem>(dbContext);

                Entities.EDimItem eDimItem = new Entities.EDimItem();
                eDimItem.Id = Guid.NewGuid();
                eDimItem.DimId = dimId;
                eDimItem.Code = code;
                eDimItem.Name = name;
                eDimItem.EffectiveDate = effectiveDate;
                eDimItem.ExpiryDate = expiryDate;
                eDimItem.Creator = userId;
                eDimItem.CreatedTime = DateTime.Now;

                diRep.Create(eDimItem);

                if (dbContext.SaveChanges() > 0)
                {
                    return new ServiceResult<Entities.EDimItem>(true, ErrorCode.COM_NoError, string.Empty, eDimItem);
                }
                else
                {
                    return new ServiceResult<Entities.EDimItem>(false, ErrorCode.COM_DBError, string.Empty);
                }
            }
        }

        public PagedList<Entities.EDim> GetDimList(string filter,int start, int limit)
        {
            using (EtlDbContext dbContext = new EtlDbContext())
            {
                if (string.IsNullOrEmpty(filter))
                {
                    EntityRepository<Entities.EDim> dRep = new EntityRepository<Entities.EDim>(dbContext);
                    List<Entities.EDim> list = dRep.GetList(p => p.IsDeleted == false && p.IsEnabled == true).Take(limit).Skip(start).ToList();
                    int total = dRep.Count(p => p.IsDeleted == false && p.IsEnabled == true);

                    return new PagedList<Entities.EDim>(true, ErrorCode.COM_NoError, string.Empty, start, limit, total, list);
                }
                else
                {
                    EntityRepository<Entities.EDim> dRep = new EntityRepository<Entities.EDim>(dbContext);
                    List<Entities.EDim> list = dRep.GetList(p => (p.Name.Contains(filter) || p.Code.Contains(filter)) && p.IsDeleted == false && p.IsEnabled == true).Take(limit).Skip(start).ToList();
                    int total = dRep.Count(p => (p.Name.Contains(filter) || p.Code.Contains(filter)) && p.IsDeleted == false && p.IsEnabled == true);

                    return new PagedList<Entities.EDim>(true, ErrorCode.COM_NoError, string.Empty, start, limit, total, list);
                }
            }
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="dimId"></param>
        /// <param name="includeOverdue">包含过期的</param>
        /// <param name="start"></param>
        /// <param name="limit"></param>
        /// <returns></returns>
        public PagedList<Entities.EDimItem> GetDimItemList(Guid dimId, bool includeOverdue, int start, int limit)
        {
            using (EtlDbContext dbContext = new EtlDbContext())
            {
                EntityRepository<Entities.EDimItem> diRep = new EntityRepository<Entities.EDimItem>(dbContext);
                if(includeOverdue)
                {
                    List<Entities.EDimItem> list = diRep.GetList(p=>p.DimId == dimId).Skip(start).Take(limit).ToList();
                    int total = diRep.Count(p => p.DimId == dimId);

                    return new PagedList<Entities.EDimItem>(true, ErrorCode.COM_NoError, string.Empty, start, limit, total, list);
                }
                else
                {
                    List<Entities.EDimItem> list = diRep.GetList(p => p.EffectiveDate < DateTime.Now && p.ExpiryDate > DateTime.Now && p.DimId == dimId).Skip(start).Take(limit).ToList();
                    int total = diRep.Count(p => p.EffectiveDate < DateTime.Now && p.ExpiryDate > DateTime.Now && p.DimId == dimId);

                    return new PagedList<Entities.EDimItem>(true, ErrorCode.COM_NoError, string.Empty, start, limit, total, list);
                }
            }
        }

        public ServiceResult DeleteDim(Guid dimId)
        {
            using (EtlDbContext dbContext = new EtlDbContext())
            {
                dbContext.Database.ExecuteSqlCommand("exec [ETL_SP_DeleteDim] @DimId={0}", dimId);

                return new ServiceResult(true, ErrorCode.COM_NoError, string.Empty);
            }
        }

        public ServiceResult DeleteDimItem(Guid dimId, Guid dimItemId)
        {
            using (EtlDbContext dbContext = new EtlDbContext())
            {
                EntityRepository<Entities.EDimItem> diRep = new EntityRepository<Entities.EDimItem>(dbContext);

                Entities.EDimItem eDimItem = diRep.Get(p => p.DimId == dimId && p.Id == dimItemId);
                if (eDimItem != null)
                {
                    diRep.Delete(eDimItem);
                    if (dbContext.SaveChanges() > 0)
                    {
                        return new ServiceResult(true, ErrorCode.COM_NoError, string.Empty);
                    }
                    else
                    {
                        return new ServiceResult(false, ErrorCode.COM_DBError, string.Empty);
                    }
                }
                else
                {
                    return new ServiceResult(false, ErrorCode.COM_DBError, string.Empty);
                }
            }
        }

        public ServiceResult<Entities.EDim> GetDim(Guid dimId)
        {
            using (EtlDbContext dbContext = new EtlDbContext())
            {
                EntityRepository<Entities.EDim> dRep = new EntityRepository<Entities.EDim>(dbContext);

                Entities.EDim eDim = dRep.Get(p => p.Id == dimId);

                if(eDim != null)
                {
                    return new ServiceResult<Entities.EDim>(true, ErrorCode.COM_NoError, ErrorCode.String(ErrorCode.COM_NoError), eDim);
                }
                else
                {
                    return new ServiceResult<Entities.EDim>(false, ErrorCode.COM_OBJNotExist, ErrorCode.String(ErrorCode.COM_OBJNotExist));
                }
            }
        }

        public ServiceResult<Entities.EDimItem> GetDimItem(Guid itemId)
        {
            using (EtlDbContext dbContext = new EtlDbContext())
            {
                EntityRepository<Entities.EDimItem> diRep = new EntityRepository<Entities.EDimItem>(dbContext);

                Entities.EDimItem eDimItem = diRep.Get(p => p.Id == itemId);

                if (eDimItem != null)
                {
                    return new ServiceResult<Entities.EDimItem>(true, ErrorCode.COM_NoError, ErrorCode.String(ErrorCode.COM_NoError), eDimItem);
                }
                else
                {
                    return new ServiceResult<Entities.EDimItem>(false, ErrorCode.COM_OBJNotExist, ErrorCode.String(ErrorCode.COM_OBJNotExist));
                }
            }
        }

        public ServiceResult UpdateDim(string userId, Guid dimId, string code, string name)
        {
            if (string.IsNullOrEmpty(name)
                || string.IsNullOrEmpty(code))
            {
                return new ServiceResult(false, ErrorCode.COM_InvalidParameter, ErrorCode.String(ErrorCode.COM_InvalidParameter));
            }

            using (EtlDbContext dbContext = new EtlDbContext())
            {
                EntityRepository<Entities.EDim> dRep = new EntityRepository<Entities.EDim>(dbContext);

                Entities.EDim eDim = dRep.Get(p => p.Id == dimId);

                if (eDim != null)
                {
                    if(dRep.Count(p=>p.Code == code && p.Id != dimId) > 0)
                    {
                        return new ServiceResult(false, ErrorCode.COM_CodeExist, ErrorCode.String(ErrorCode.COM_CodeExist));
                    }

                    eDim.Code = code;
                    eDim.Name = name;
                    eDim.Creator = userId;
                    eDim.CreatedTime = DateTime.Now;
                    dRep.Update(eDim);

                    try
                    {
                        dbContext.SaveChanges();

                        return new ServiceResult(true, ErrorCode.COM_NoError, ErrorCode.String(ErrorCode.COM_NoError));
                    }
                    catch(Exception ex)
                    {
                        Logger.ErrorToTag(Library.LogTAG, string.Format("更新维度:{0}出错,ex:{1}", dimId, ex));

                        return new ServiceResult(false, ErrorCode.COM_Exception, ErrorCode.String(ErrorCode.COM_Exception));
                    }
                }
                else
                {
                    return new ServiceResult(false, ErrorCode.COM_OBJNotExist, ErrorCode.String(ErrorCode.COM_OBJNotExist));
                }
            }
        }

        public ServiceResult UpdateDimItem(string userId, Guid itemId, string code, string name)
        {
            if (string.IsNullOrEmpty(name)
                || string.IsNullOrEmpty(code))
            {
                return new ServiceResult(false, ErrorCode.COM_InvalidParameter, ErrorCode.String(ErrorCode.COM_InvalidParameter));
            }

            using (EtlDbContext dbContext = new EtlDbContext())
            {
                EntityRepository<Entities.EDimItem> diRep = new EntityRepository<Entities.EDimItem>(dbContext);

                Entities.EDimItem eDimItem = diRep.Get(p => p.Id == itemId);

                if (eDimItem != null)
                {
                    if (diRep.Count(p => p.DimId == eDimItem.DimId && p.Id!= itemId && p.Code == code) > 0)
                    {
                        return new ServiceResult(false, ErrorCode.COM_CodeExist, ErrorCode.String(ErrorCode.COM_CodeExist));
                    }

                    eDimItem.Code = code;
                    eDimItem.Name = name;
                    eDimItem.Creator = userId;
                    eDimItem.CreatedTime = DateTime.Now;
                    diRep.Update(eDimItem);

                    try
                    {
                        dbContext.SaveChanges();

                        return new ServiceResult(true, ErrorCode.COM_NoError, ErrorCode.String(ErrorCode.COM_NoError));
                    }
                    catch (Exception ex)
                    {
                        Logger.ErrorToTag(Library.LogTAG, string.Format("更新维度项:{0}出错,ex:{1}", itemId, ex));

                        return new ServiceResult(false, ErrorCode.COM_Exception, ErrorCode.String(ErrorCode.COM_Exception));
                    }
                }
                else
                {
                    return new ServiceResult(false, ErrorCode.COM_OBJNotExist, ErrorCode.String(ErrorCode.COM_OBJNotExist));
                }
            }
        }
    }
}
